Generated code - QuerySpec, Specifying the type of a DynamicQuery resultset
A dynamic query is an un-typed projection of data. In the raw form, this
query is returned in a list of object arrays. To have a typed projection,
the a projectior func has to be specified. This can be done in two ways:
- Use the DynamicQuery.WithProjector<T>(Func<ProjectionRow,
T> projectorFunc) method. The Func specified receives a
ProjectionRow object, and converts it into an instance of type T.
The WithProjector method returns a DynamicQuery<T> instance,
instead of a DynamicQuery instance.
- Use the Query.Select(Expression<Func<T>> projection)
method. This method is equal to query.Select(projection) where
projection is one or more elements, however the projection lambda is
converted into a Func<ProjectionRow, T> internally.
Fetching a DynamicQuery uses a projection fetch, so type converters
and the like are taken into account.
A Dynamic query can be returned as one of the following result types:
- List<object[]>. The projection is assumed to have one or more
elements and every element's value is a position in the returned object
array. Per row of the main query one object array is returned. Results of
nested queries are seen as the result of an element and are placed at the
position in the object array the nested query has in the projection.
- List<T>. The projection of the query is assumed to have
one field
and every ProjectionRow is converted to a single value of type T. If T
contains multiple fields or a CTor has to be called on T, use the
WithProjector<T> Func/delegate
approach of List<T> with a constructor delegate.
- List<T> using the WithProjector delegate. Using the
WithProjector<T> method or the Select(Expression<Func<>>) method, a
Func
(delegate) can be specified which contains the constructor call to convert
the ProjectionRow into an instance of type T. The T instances are stored in
a list which is returned. The Func/delegate can use index based indexers to
obtain values, or use the method Get<T>(name) to obtain the value of
property name as type T. The delegate is of type: Func<ProjectionRow,
T>.
Examples
Below are three ways to define the same dynamic query. qf is the
QueryFactory instance.
DynamicQuery, returning List<object[]>
var q = qf.Order
.Where(OrderFields.CustomerId.StartsWith("C"))
.OrderBy(OrderFields.CustomerId.Ascending())
.Select(OrderFields.OrderId, OrderFields.CustomerId, OrderFields.EmployeeId, OrderFields.OrderDate)
DynamicQuery<T>, using WithProjector<T>, returning List<T>
var q = qf.Order
.Where(OrderFields.CustomerId.StartsWith("C"))
.OrderBy(OrderFields.CustomerId.Ascending())
.Select(OrderFields.OrderId, OrderFields.CustomerId, OrderFields.EmployeeId, OrderFields.OrderDate)
.WithProjector(r => new
{
OrderId = (int)r[0],
CustomerId = (string)r[1],
EmployeeId = (int?)r[2],
OrderDate = (DateTime?)r[3]
});
DynamicQuery<T>, using .Select(Expression<Func<>>), returning List<T>
var q = qf.Order
.Where(OrderFields.CustomerId.StartsWith("C"))
.OrderBy(OrderFields.CustomerId.Ascending())
.Select(() => new
{
OrderId = OrderFields.OrderId.ToValue<int>(),
CustomerId = OrderFields.CustomerId.ToValue<string>(),
EmployeeId = OrderFields.EmployeeId.ToValue<int?>(),
OrderDate = OrderFields.OrderDate.ToValue<DateTime?>()
});